﻿#include "Server.h"


#ifdef WIN32
#pragma comment(lib, "ws2_32.lib")
#include <WinSock2.h>
#include <WS2tcpip.h>
#endif

#include <event2/event.h>
#include <event2/http.h>
#include <event2/buffer.h>
#include <event2/http_struct.h>
#include <json/json.h>
#include <json/value.h>
#include <thread>
#include "Control.h"
#include "Config.h"
#include "Scheduler.h"
#include "Utils/Log.h"
#include "Utils/Common.h"
#include "Utils/Base64.h"
#include "ModelConfig.h"
#include "Algorithm.h"
#include "WorkerImage.h"

using namespace AVSAnalyzer;

#define RECV_BUF_MAX_SIZE 1024*8

Server::Server() {
#ifdef WIN32
    WSADATA wdSockMsg;
    int s = WSAStartup(MAKEWORD(2, 2), &wdSockMsg);

    if (0 != s)
    {
        switch (s)
        {
        case WSASYSNOTREADY: printf("重启电脑，或者检查网络库");   break;
        case WSAVERNOTSUPPORTED: printf("请更新网络库");  break;
        case WSAEINPROGRESS: printf("请重新启动");  break;
        case WSAEPROCLIM:  printf("请关闭不必要的软件，以确保有足够的网络资源"); break;
        }
    }

    if (2 != HIBYTE(wdSockMsg.wVersion) || 2 != LOBYTE(wdSockMsg.wVersion))
    {
        LOGE("网络库版本错误");
        return;
    }
#endif
}
Server::~Server() {
    LOGE("");
#ifdef WIN32
    WSACleanup();
#endif
}

void Server::start(void* arg) {
    Scheduler* scheduler = (Scheduler*)arg;
    scheduler->setState(true);

    std::thread([](Scheduler *scheduler) 
    {
        LOGI("启动分析器服务：%s", scheduler->getConfig()->analyzerHost.data());
        
        event_config* evt_config = event_config_new();
        struct event_base* base = event_base_new_with_config(evt_config);
        struct evhttp* http = evhttp_new(base);
        evhttp_set_default_content_type(http, "text/html; charset=utf-8");

        evhttp_set_timeout(http, 30);
        // 设置路由
        evhttp_set_cb(http, "/", api_index, nullptr);
        evhttp_set_cb(http, "/api/health", api_health, scheduler);
        evhttp_set_cb(http, "/api/controls", api_controls, scheduler);
        evhttp_set_cb(http, "/api/control", api_control, scheduler);
        evhttp_set_cb(http, "/api/control/add", api_control_add, scheduler);
        evhttp_set_cb(http, "/api/control/cancel", api_control_cancel, scheduler);
        evhttp_set_cb(http, "/api/algorithms", api_algorithms, scheduler);
        evhttp_set_cb(http, "/api/algorithm", api_algorithm_detail, scheduler);
        // 添加图片分析API
        evhttp_set_cb(http, "/api/analyze/image", api_analyze_image, scheduler);

        evhttp_bind_socket(http, "0.0.0.0", scheduler->getConfig()->analyzerPort);
        event_base_dispatch(base);

        event_base_free(base);
        evhttp_free(http);
        event_config_free(evt_config);

        scheduler->setState(false);

    }, scheduler).detach();
}

void api_index(struct evhttp_request* req, void* arg) {   
    Json::Value result_urls;
    result_urls["/api"] = "this api version 1.0";
    result_urls["/api/health"] = "check health";
    result_urls["/api/controls"] = "get all control being analyzed";
    result_urls["/api/control"] = "get control being analyzed";
    result_urls["/api/control/add"] = "add control";
    result_urls["/api/control/cancel"] = "cancel control";    
    
    Json::Value result;
    result["urls"] = result_urls;

    struct evbuffer* buff = evbuffer_new();
    evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
    evhttp_send_reply(req, HTTP_OK, nullptr, buff);
    evbuffer_free(buff);

}
void api_health(struct evhttp_request* req, void* arg) {
    int result_code = 0;
    std::string result_msg = "error";

    // 健康检测
    result_code = 1000;
    result_msg = "current service health";

    Json::Value result;
    result["msg"] = result_msg;
    result["code"] = result_code;

    struct evbuffer* buff = evbuffer_new();
    evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
    evhttp_send_reply(req, HTTP_OK, nullptr, buff);
    evbuffer_free(buff);
}

void api_controls(struct evhttp_request* req, void* arg) 
{  
    Scheduler* scheduler = (Scheduler*)arg;
    char buf[RECV_BUF_MAX_SIZE];
    parse_post(req, buf);

    Json::CharReaderBuilder builder;
    const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
    Json::Value root;
    JSONCPP_STRING errs;

    Json::Value result_data;
    Json::Value result_data_item;
    int result_code = 0;
    std::string result_msg = "error";
    Json::Value result;

    if (reader->parse(buf, buf + std::strlen(buf), &root, &errs) && errs.empty()) 
    {
        std::vector<Control*> controls;
        int len = scheduler->apiControls(controls);

        if (len > 0) {
            int64_t curTimestamp = getCurTimestamp();
            int64_t startTimestamp = 0;
            for (int i = 0; i < controls.size(); i++)
            {
                startTimestamp = controls[i]->startTimestamp;

                result_data_item["code"] = controls[i]->code.data();
                result_data_item["streamUrl"] = controls[i]->streamUrl.data();
                result_data_item["pushStream"] = controls[i]->pushStream;
                result_data_item["pushStreamUrl"] = controls[i]->pushStreamUrl.data();
                result_data_item["algorithmCode"] = controls[i]->algorithmCode.data();
                result_data_item["objectCode"] = controls[i]->objectCode.data();
                result_data_item["recognitionRegion"] = controls[i]->recognitionRegion.data();
                result_data_item["checkFps"] = controls[i]->checkFps;
                result_data_item["startTimestamp"] = startTimestamp;
                result_data_item["liveMilliseconds"] = curTimestamp - startTimestamp;

                result_data.append(result_data_item);
            }
            result["data"] = result_data;
            result_code = 1000;
            result_msg = "success";
        }
        else {
            result_msg = "the number of control exector is empty";
        }
    }
    else {
        result_msg = "invalid request parameter";
    }
    result["msg"] = result_msg;
    result["code"] = result_code;
    //LOGI("\n \t request:%s \n \t response:%s", root.toStyledString().data(), result.toStyledString().data());

    struct evbuffer* buff = evbuffer_new();
    evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
    evhttp_send_reply(req, HTTP_OK, nullptr, buff);
    evbuffer_free(buff);
}
void api_control(struct evhttp_request* req, void* arg) 
{
    Scheduler* scheduler = (Scheduler*)arg;
    char buf[RECV_BUF_MAX_SIZE];
    parse_post(req, buf);

    Json::CharReaderBuilder builder;
    const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
    Json::Value root;
    JSONCPP_STRING errs;

    Json::Value result_control;
    int result_code = 0;
    std::string result_msg = "error";    

    if (reader->parse(buf, buf + std::strlen(buf), &root, &errs) && errs.empty()) {
        Control* control = NULL;
        if (root["code"].isString()) {
            std::string code = root["code"].asCString();
            control = scheduler->apiControl(code);
        }

        if (control) {
            result_control["code"] = control->code;
            result_control["checkFps"] = control->checkFps;

            result_code = 1000;
            result_msg = "success";
        }
        else {
            result_msg = "the control does not exist";
        }
    }
    else {
        result_msg = "invalid request parameter";
    }

    Json::Value result;
    result["control"] = result_control;
    result["msg"] = result_msg;
    result["code"] = result_code;
    LOGI("\n \t request:%s \n \t response:%s", root.toStyledString().data(), result.toStyledString().data());

    struct evbuffer* buff = evbuffer_new();
    evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
    evhttp_send_reply(req, HTTP_OK, nullptr, buff);
    evbuffer_free(buff);
}
void api_control_add(struct evhttp_request* req, void* arg) 
{
    Scheduler* scheduler = (Scheduler*)arg;
    char buf[RECV_BUF_MAX_SIZE];
    parse_post(req, buf);

    Json::CharReaderBuilder builder;
    const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
    Json::Value root;
    JSONCPP_STRING errs;

    int result_code = 0;
    std::string result_msg = "error";

    if (reader->parse(buf, buf + std::strlen(buf), &root, &errs) && errs.empty()) 
    {
        Control control;
        control.code = root["code"].asCString();                    // 布控编号（上层传入，确定具体任务名称）
        control.streamUrl = root["streamUrl"].asString();           // 拉流地址
        control.pushStream = root["pushStream"].asBool();           // 是否需要推流
        control.pushStreamUrl = root["pushStreamUrl"].asString();   // 推流地址
        control.algorithmCode = root["algorithmCode"].asString();   // 算法编号(来确定对应哪个具体算法)
        // begin 现计划一下参数都不从接口设置，而是从配置文件中读取
        // control.objects = root["objects"].asString();
        // control.objects_v1 = split(control.objects, ",");
        // control.objects_v1_len = control.objects_v1.size();
        // control.objectCode = root["objectCode"].asString();
        // end
        control.recognitionRegion = root["recognitionRegion"].asString();   // 识别区域
        control.threshold = root["threshold"].asDouble();                   // 目标检测得分阈值
        control.checkFps = root["checkFps"].asInt();                        // 识别帧率
        control.minInterval = 0;
        
        if (root["minInterval"].isString()) 
        {
            control.minInterval = stoi(root["minInterval"].asString()) * 1000;//客户端传递过的该参数单位是秒
        }
        //强制设置报警时间最大不能超过3分钟=180000毫秒
        if (control.minInterval > 180000)
         {
            control.minInterval = 180000;
        }

        if (control.validateAdd(result_msg)) 
        {
            scheduler->apiControlAdd(&control, result_code, result_msg);
        }
    }
    else 
    {
        result_msg = "invalid request parameter";
    }

    Json::Value result;
    result["msg"] = result_msg;
    result["code"] = result_code;

    LOGI("\n \t request:%s \n \t response:%s", root.toStyledString().data(), result.toStyledString().data());

    struct evbuffer* buff = evbuffer_new();
    evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
    evhttp_send_reply(req, HTTP_OK, nullptr, buff);
    evbuffer_free(buff);
}

void api_control_cancel(struct evhttp_request* req, void* arg) 
{
    Scheduler* scheduler = (Scheduler*)arg;
    char buf[RECV_BUF_MAX_SIZE];
    parse_post(req, buf);

    Json::CharReaderBuilder builder;
    const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());

    Json::Value root;
    JSONCPP_STRING errs;

    int result_code = 0;
    std::string result_msg = "error";

    if (reader->parse(buf, buf + std::strlen(buf), &root, &errs) && errs.empty()) 
    {
        Control control;
        if (root["code"].isString()) 
        {
            control.code = root["code"].asCString();
        }
        if (control.validateCancel(result_msg)) 
        {
            scheduler->apiControlCancel(&control, result_code, result_msg);
        }
    }
    else 
    {
        result_msg = "invalid request parameter";
    }

    Json::Value result;
    result["msg"] = result_msg;
    result["code"] = result_code;

    LOGI("\n \t request:%s \n \t response:%s", root.toStyledString().data(), result.toStyledString().data());

    struct evbuffer* buff = evbuffer_new();
    evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
    evhttp_send_reply(req, HTTP_OK, nullptr, buff);
    evbuffer_free(buff);
}

void api_algorithms(struct evhttp_request* req, void* arg) {
    Scheduler* scheduler = (Scheduler*)arg;
    
    struct evbuffer* buff = evbuffer_new();
    Json::Value result;
    
    try {
        result["code"] = 1000;
        result["msg"] = "success";
        
        // 获取算法列表
        Json::Value algorithms(Json::arrayValue);
        const auto& algorithmInstances = scheduler->getAlgorithms();
        
        // 遍历所有算法实例
        for(const auto& algorithm : algorithmInstances) {  // algorithm 是 unique_ptr<Algorithm>
            if (!algorithm.get()) continue;  // 检查智能指针

            Json::Value algo;
            const auto& config = algorithm->getConfig();  // 通过->访问成员函数
            
            algo["name"] = config.name;              // 算法名称
            algo["type"] = config.type;              // 算法类型
            algo["path"] = config.path;              // 模型路径
            
            // 添加支持的类别
            Json::Value classes(Json::arrayValue);
            for(size_t i = 0; i < config.className.size(); i++) {
                Json::Value classInfo;
                classInfo["id"] = static_cast<int>(i);
                classInfo["name"] = config.className[i];
                classes.append(classInfo);
            }
            algo["classes"] = classes;
            
            // 添加算法参数
            algo["score_threshold"] = config.scoreThreshold;
            algo["nms_threshold"] = config.nmsThreshold;
            
            algorithms.append(algo);
        }
        
        result["algorithms"] = algorithms;
    }
    catch(const std::exception& e) {
        result["code"] = 1001;
        result["msg"] = std::string("Error: ") + e.what();
        LOGE("Get algorithms error: %s", e.what());
    }
    
    // 发送响应
    evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
    evhttp_send_reply(req, HTTP_OK, nullptr, buff);
    evbuffer_free(buff);
}

void api_algorithm_detail(struct evhttp_request* req, void* arg) {
    Scheduler* scheduler = (Scheduler*)arg;
    
    // 解析POST请求
    char buf[RECV_BUF_MAX_SIZE];
    parse_post(req, buf);

    struct evbuffer* buff = evbuffer_new();
    Json::Value result;
    
    try {
        // 解析请求JSON
        Json::CharReaderBuilder builder;
        const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
        Json::Value root;
        JSONCPP_STRING errs;

        if (!reader->parse(buf, buf + std::strlen(buf), &root, &errs) || !root.isMember("type")) {
            result["code"] = 1002;
            result["msg"] = "Missing type parameter";
            throw std::runtime_error("Invalid request parameter");
        }

        std::string type = root["type"].asString();
        
        // 获取指定算法的配置
        const auto& algorithms = scheduler->getAlgorithms();
        bool found = false;
        
        for (const auto& algorithm : algorithms) {
            if (!algorithm.get()) continue;
            
            const auto& config = algorithm->getConfig();
            if (config.type == type) {
                found = true;
                
                result["code"] = 1000;
                result["msg"] = "success";
                
                Json::Value algo;
                algo["name"] = config.name;
                algo["type"] = config.type;
                algo["path"] = config.path;
                
                // 添加类别信息
                Json::Value classes(Json::arrayValue);
                for(size_t i = 0; i < config.className.size(); i++) {
                    Json::Value classInfo;
                    classInfo["id"] = static_cast<int>(i);
                    classInfo["name"] = config.className[i];
                    classes.append(classInfo);
                }
                algo["classes"] = classes;
                
                // 添加算法参数
                algo["score_threshold"] = config.scoreThreshold;
                algo["nms_threshold"] = config.nmsThreshold;
                
                result["algorithm"] = algo;
                break;
            }
        }
        
        if (!found) {
            result["code"] = 1004;
            result["msg"] = "Algorithm not found";
        }
    }
    catch(const std::exception& e) {
        if (result["code"].asInt() == 0) {
            result["code"] = 1001;
            result["msg"] = std::string("Error: ") + e.what();
        }
        LOGE("Get algorithm detail error: %s", e.what());
    }
    
    // 发送响应
    evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
    evhttp_send_reply(req, HTTP_OK, nullptr, buff);
    evbuffer_free(buff);
}

void api_analyze_image(struct evhttp_request* req, void* arg) 
{
    Scheduler* scheduler = (Scheduler*)arg;
    
    // 获取请求内容
    struct evbuffer* input_buffer = evhttp_request_get_input_buffer(req);
    size_t input_size = evbuffer_get_length(input_buffer);
    
    // 检查请求大小
    if (input_size <= 0 || input_size > 10 * 1024 * 1024) { // 限制最大10MB
        Json::Value result;
        result["code"] = 1003;
        result["msg"] = "Invalid image size";
        
        struct evbuffer* buff = evbuffer_new();
        evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
        evhttp_send_reply(req, HTTP_OK, nullptr, buff);
        evbuffer_free(buff);
        return;
    }
    
    // 检查Content-Type
    const char* content_type = evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type");
    bool is_json = content_type && strstr(content_type, "application/json");
    
    std::string algorithm_code = "yolov8"; // 默认算法
    char* image_data = nullptr;
    size_t image_size = 0;
    
    if (is_json) {
        // 处理JSON格式请求
        char* json_data = new char[input_size + 1];
        evbuffer_copyout(input_buffer, json_data, input_size);
        json_data[input_size] = '\0';
        
        Json::CharReaderBuilder builder;
        const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
        Json::Value root;
        JSONCPP_STRING errs;
        
        if (reader->parse(json_data, json_data + input_size, &root, &errs) && errs.empty()) {
            if (root.isMember("algorithmCode") && root["algorithmCode"].isString()) {
                algorithm_code = root["algorithmCode"].asString();
            }
            
            if (root.isMember("image") && root["image"].isString()) {
                std::string base64_image = root["image"].asString();
                // 解码Base64
                Base64 base64;
                std::string decoded_data = base64.decode(base64_image);
                image_size = decoded_data.size();
                image_data = new char[image_size];
                memcpy(image_data, decoded_data.data(), image_size);
            } else {
                // 缺少图片数据
                Json::Value result;
                result["code"] = 1002;
                result["msg"] = "Missing image data";
                
                struct evbuffer* buff = evbuffer_new();
                evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
                evhttp_send_reply(req, HTTP_OK, nullptr, buff);
                evbuffer_free(buff);
                delete[] json_data;
                return;
            }
        } else {
            // JSON解析失败
            Json::Value result;
            result["code"] = 1002;
            result["msg"] = "Invalid JSON format";
            
            struct evbuffer* buff = evbuffer_new();
            evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
            evhttp_send_reply(req, HTTP_OK, nullptr, buff);
            evbuffer_free(buff);
            delete[] json_data;
            return;
        }
        
        delete[] json_data;
    } else {
        // 处理二进制格式请求
        const char* alg_code = evhttp_find_header(evhttp_request_get_input_headers(req), "X-Algorithm-Code");
        if (alg_code) {
            algorithm_code = alg_code;
        }
        
        image_size = input_size;
        image_data = new char[image_size];
        evbuffer_copyout(input_buffer, image_data, image_size);
    }
    
    // 创建控制对象
    Control control;
    control.code = "image_" + std::to_string(getCurTimestamp()); // 生成唯一ID
    control.algorithmCode = algorithm_code;
    
    // 创建WorkerImage对象
    WorkerImage* worker = new WorkerImage(scheduler, &control);
    
    // 启动图片处理
    std::string msg;
    bool success = worker->startImageProcess(image_data, image_size, msg);
    
    // 释放图片数据
    delete[] image_data;
    
    // 准备响应
    Json::Value result;
    if (success) {
        // 获取检测结果
        std::vector<DetectObject> detects = worker->getDetectResults();
        
        result["code"] = 1000;
        result["msg"] = "success";
        
        // 构建检测结果数组
        Json::Value data(Json::arrayValue);
        for (const auto& detect : detects) {
            Json::Value item;
            item["class"] = detect.class_name;
            item["score"] = detect.class_score;
            
            // 构建边界框数组 [x1, y1, x2, y2]
            Json::Value box(Json::arrayValue);
            box.append(detect.x1);
            box.append(detect.y1);
            box.append(detect.x2);
            box.append(detect.y2);
            item["box"] = box;
            
            data.append(item);
        }
        
        result["data"] = data;
    } else {
        result["code"] = 1002;
        result["msg"] = "Failed to analyze image: " + msg;
    }
    
    // 发送响应
    struct evbuffer* buff = evbuffer_new();
    evbuffer_add_printf(buff, "%s", result.toStyledString().c_str());
    evhttp_send_reply(req, HTTP_OK, nullptr, buff);
    evbuffer_free(buff);
}


void parse_get(struct evhttp_request* req, struct evkeyvalq* params) 
{
    if (req == nullptr) {
        return;
    }
    const char* url = evhttp_request_get_uri(req);
    if (url == nullptr) 
    {
        return;
    }
    struct evhttp_uri* decoded = evhttp_uri_parse(url);
    if (!decoded) 
    {
        return;
    }
    const char* path = evhttp_uri_get_path(decoded);
    if (path == nullptr) 
    {
        path = "/";
    }
    char* query = (char*)evhttp_uri_get_query(decoded);
    if (query == nullptr) 
    {
        return;
    }
    evhttp_parse_query_str(query, params);
}
// 解析post请求
void parse_post(struct evhttp_request* req, char* buf) 
{
    size_t post_size = 0;

    post_size = evbuffer_get_length(req->input_buffer);
    if (post_size <= 0) 
    {
        //        printf("====line:%d,post msg is empty!\n",__LINE__);
        return;
    }
    else 
    {
        size_t copy_len = post_size > RECV_BUF_MAX_SIZE ? RECV_BUF_MAX_SIZE : post_size;
        //        printf("====line:%d,post len:%d, copy_len:%d\n",__LINE__,post_size,copy_len);
        memcpy(buf, evbuffer_pullup(req->input_buffer, -1), copy_len);
        buf[post_size] = '\0';
        //        printf("====line:%d,post msg:%s\n",__LINE__,buf);
    }
}